using System;
using System.Collections.Generic;
using System.Text;
using WCSFContrib.Extensions.CompositeWeb.Interfaces;
using Microsoft.Practices.CompositeWeb.Interfaces;
using Microsoft.Practices.CompositeWeb;
using System.Reflection;
using Microsoft.Practices.CompositeWeb.Utility;
using System.Globalization;
using System.Diagnostics;

namespace WCSFContrib.Extensions.CompositeWeb.Services
{
    public class ServiceLoader : IServiceLoader
    {
        /// <summary>
        /// Initializes a new instance of <see cref="ServiceLoaderService"/>.
        /// </summary>
        public ServiceLoader()
        {
        }

        /// <summary>
        /// Loads the specified services into the given container.
        /// </summary>
        /// <param name="compositionContainer">The container into which create and add the configured services.</param>
        /// <param name="services">The list of services to load.</param>
        public void Load(ICompositionContainer compositionContainer, params ServiceInfo[] services)
        {
            Guard.ArgumentNotNull(compositionContainer, "compositionContainer");
            Guard.ArgumentNotNull(services, "services");

            if (!typeof(CompositionContainer).IsAssignableFrom(compositionContainer.GetType()))
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Properties.Resources.ContainerIsNotCompositionContainer, typeof(CompositionContainer).FullName), "compositionContainer");


            LoadServices(compositionContainer, services);
        }

        private void LoadServices(ICompositionContainer container, ServiceInfo[] services)
        {
            foreach (ServiceInfo service in services)
            {
                LoadServices(container, service);
            }
        }

        private void LoadServices(ICompositionContainer container, ServiceInfo service)
        {
            IServiceCollection serviceCollection;

            switch (service.Scope)
            {
                case ServiceScope.Global:
                    serviceCollection = (container.Parent == null) ? container.Services : container.Parent.Services;
                    break;

                case ServiceScope.Module:
                    serviceCollection = container.Services;
                    break;

                default:
                    serviceCollection = container.Services;
                    break;
            }

            serviceCollection.AddNew(service.Type, service.RegisterAs);
        }
    }
}